from abc import ABC, abstractmethod
from typing import List, Optional, TypeVar, Generic
from django.db import models

T = TypeVar('T', bound=models.Model)

class IRepository(Generic[T], ABC):
    """仓储接口基类"""
    
    @abstractmethod
    def get_by_id(self, id: int) -> Optional[T]:
        pass
    
    @abstractmethod
    def get_all(self) -> List[T]:
        pass
    
    @abstractmethod
    def create(self, **kwargs) -> T:
        pass
    
    @abstractmethod
    def update(self, id: int, **kwargs) -> T:
        pass
    
    @abstractmethod
    def delete(self, id: int) -> bool:
        pass

class BaseRepository(Generic[T], IRepository[T]):
    """基础仓储实现"""
    def __init__(self, model_class):
        self.model_class = model_class
    
    def get_by_id(self, id: int) -> Optional[T]:
        try:
            return self.model_class.objects.get(Id=id)
        except self.model_class.DoesNotExist:
            return None
    
    def get_all(self) -> List[T]:
        return list(self.model_class.objects.all())
    
    def create(self, **kwargs) -> T:
        return self.model_class.objects.create(**kwargs)
    
    def update(self, id: int, **kwargs) -> T:
        instance = self.get_by_id(id)
        if not instance:
            raise self.model_class.DoesNotExist(f"对象 {id} 不存在")
        
        for key, value in kwargs.items():
            setattr(instance, key, value)
        instance.save()
        return instance
    
    def delete(self, id: int) -> bool:
        instance = self.get_by_id(id)
        if instance:
            instance.delete()
            return True
        return False
    
    def filter(self, **filters) -> List[T]:
        return list(self.model_class.objects.filter(**filters))
    
    def get_or_none(self, **filters) -> Optional[T]:
        try:
            return self.model_class.objects.get(**filters)
        except self.model_class.DoesNotExist:
            return None